package pro.cherish.knowledgeormmysql.config.mybatis.typeHandler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author 创建人：lys
 * @version 版本号：V1.0
 * <p>
 * ***************************修订记录************************************
 * 2020-6-2 lys 创建该类功能。
 * **********************************************************************
 * </p>
 * @ClassName 类名：JsonTypeHandler
 * @Description 功能说明：配置自定义的TypeHandler，处理JSON与对象直接互转问题，不需要手动转换
 * <p>
 *  @MappedTypes指定支持的JAVA类型，@MappedJdbcTypes指定jdbctype
 *  @MappedTypes(value = {JSONObject.class, Test.class})
 *  @MappedJdbcTypes(value = {JdbcType.VARCHAR}, includeNullJdbcType = true)
 *  现在使用的方式是
 *  表：从json字符串转java实体时使用
 *  @TableName(value = "msg_receive", autoResultMap = true)
 *  字段：作用与序列化到数据库
 *  @TableField(typeHandler = JsonTypeHandlers.class)
 *  private Test test;
 *  @TableField(typeHandler = JsonTypeHandlers.class)
 * 	private List<Test> testList;
 * </p>
 * **********************************************************************
 * @date 创建日期： 2020-6-2 
 */
@MappedJdbcTypes(JdbcType.VARCHAR)
public class JsonTypeHandler<T extends Object> extends BaseTypeHandler<T> {

	private Class<T> clazz;

	public JsonTypeHandler(Class<T> clazz) {
		if (clazz == null) {
			throw new IllegalArgumentException("Type argument cannot be null");
		}
		this.clazz = clazz;
	}

	/**
	 * 设置非空参数
	 * @param ps
	 * @param i
	 * @param parameter
	 * @param jdbcType
	 * @throws SQLException
	 */
	@Override
	public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
		ps.setString(i, JSON.toJSONString(parameter));
	}

	/**
	 * 根据列名，获取可以为空的结果
	 * @param rs
	 * @param columnName
	 * @return
	 * @throws SQLException
	 */
	@Override
	public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
		String sqlJson = rs.getString(columnName);
		if (null != sqlJson) {
			return JSONObject.parseObject(sqlJson, clazz);
		}
		return null;
	}

	/**
	 * 根据列索引，获取可以为空的结果
	 * @param rs
	 * @param columnIndex
	 * @return
	 * @throws SQLException
	 */
	@Override
	public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
		String sqlJson = rs.getString(columnIndex);
		if (null != sqlJson) {
			return JSONObject.parseObject(sqlJson, clazz);
		}
		return null;
	}

	@Override
	public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
		String sqlJson = cs.getString(columnIndex);
		if (null != sqlJson) {
			return JSONObject.parseObject(sqlJson, clazz);
		}
		return null;
	}
}
